#include "base/AccessRepeater.h"
#include "base/Simulator.h"
#include "util/Logger.h"

AccessRepeater::AccessRepeater () {
    clear();
}

void AccessRepeater::clear () {
    walk = 0;
    count = 0;
}

void AccessRepeater::reset () {
    walk = 0;
}

void AccessRepeater::skip () {
    walk++;
}

bool AccessRepeater::isRegistered () {
    if (walk < count) {
        return true;
    } else {
        return false;
    }
}

uint bytesForType(WordAccessType type) {
    if (type == BLOCKACCESS_LOAD || type == BLOCKACCESS_STORE) {
        return global_sim->cfg.blocksize;
    } else {
        return WORD_SIZE;
    }
}

void AccessRepeater::getValue (VA wordAddress, WordAccessType type, uint* dest) {
    ASSERT(wordAddress == accesses[walk].address);
    ASSERT(type == accesses[walk].type);
    ASSERT(walk < count);

    memcpy(dest, accesses[walk++].data, bytesForType(type));
}
    
void AccessRepeater::registerAccess (VA wordAddress,
                                     uint* data,
                                     WordAccessType type)
{
    if (count >= MAX_ACCESSES) {
        Log->e("AccessRepeater: too many accesses.\n");
    }

    accesses[count].address = wordAddress;
    memcpy(accesses[count].data, data, bytesForType(type));
    accesses[count].type = type;

    count++;
    walk++;
}
